Skip to content

#734 fix busy loop in run_loop#736

Merged
AlexInLog merged 3 commits into
v2from
fix_busy_loop
Feb 15, 2026
Merged

#734 fix busy loop in run_loop#736
AlexInLog merged 3 commits into
v2from
fix_busy_loop

Conversation

@AlexInLog

@AlexInLog AlexInLog commented Feb 13, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Refactor
    • Improved scheduler efficiency by refining wake-up conditions. The scheduler now delays activations until the next scheduled task is ready, reducing unnecessary system wake-ups while maintaining reliable task execution.

@coderabbitai

coderabbitai Bot commented Feb 13, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The pull request modifies the wake-up condition for a condition variable in run_loop.hpp. The predicate was tightened to require both a non-empty queue AND the top scheduled item being ready, replacing the previous logic that woke up when either condition was true.

Changes

Cohort / File(s) Summary
Condition Variable Wake Predicate
src/rpp/rpp/schedulers/run_loop.hpp
Tightened the condition variable wake-up predicate in the pop operation to only wake when both the queue is non-empty AND the top item's timepoint is ready (≤ now), eliminating premature wake-ups when items exist but aren't yet due.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit's whisper, soft and low:
"Wake only when the time is right,
No early stirring, don't you know—
Let sleeping threads await the light!" 🐰⏰

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix busy loop in run_loop' accurately describes the main change: tightening the wake-up condition to prevent unnecessary wake-ups and busy looping.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into v2

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix_busy_loop

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/rpp/rpp/schedulers/run_loop.hpp (1)

62-69: Pre-existing: stale timeout when a nearer-deadline item is enqueued mid-wait.

If a new schedulable with an earlier timepoint is inserted via emplace_and_notify while wait_for is blocked, the notification fires and the predicate is re-evaluated. If the new item isn't due yet, wait_for resumes sleeping for the remaining portion of the original (longer) timeout. This can delay processing of the newly enqueued item by up to old_top_time − new_top_time.

Not introduced by this PR and the busy-loop fix is clearly more important, but worth keeping in mind if precise scheduling latency matters. A possible future approach: after the predicate returns false on a spurious/notify wake, break out of wait_for and loop back to recompute the timeout from the new queue top.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

BENCHMARK RESULTS (AUTOGENERATED)

ci-ubuntu-gcc

General

name rxcpp rpp prev rpp ratio rpp no optimization
Subscribe empty callbacks to empty observable 302.68 ns 1.87 ns 1.88 ns 0.99 1.55 ns
Subscribe empty callbacks to empty observable via pipe operator 304.54 ns 1.87 ns 1.86 ns 1.00 1.55 ns

Sources

name rxcpp rpp prev rpp ratio rpp no optimization
from array of 1 - create + subscribe + immediate 692.07 ns 0.31 ns 0.31 ns 1.00 0.31 ns
from array of 1 - create + subscribe + current_thread 1049.27 ns 3.73 ns 3.73 ns 1.00 3.73 ns
concat_as_source of just(1 immediate) create + subscribe 2271.10 ns 113.75 ns 115.07 ns 0.99 115.66 ns
defer from array of 1 - defer + create + subscribe + immediate 749.24 ns 0.31 ns 0.31 ns 1.00 0.31 ns
interval - interval + take(3) + subscribe + immediate 2146.32 ns 59.63 ns 59.59 ns 1.00 59.61 ns
interval - interval + take(3) + subscribe + current_thread 2992.71 ns 32.65 ns 32.65 ns 1.00 34.49 ns
from array of 1 - create + as_blocking + subscribe + new_thread 34281.87 ns 32869.17 ns 34768.53 ns 0.95 32386.00 ns
from array of 1000 - create + as_blocking + subscribe + new_thread 43008.50 ns 55804.90 ns 58446.65 ns 0.95 56364.71 ns
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe 3552.31 ns 140.04 ns 136.74 ns 1.02 147.65 ns

Filtering Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take(1)+subscribe 1121.35 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+filter(true)+subscribe 878.94 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,2)+skip(1)+subscribe 1003.64 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,1,2)+distinct_until_changed()+subscribe 898.88 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,2)+first()+subscribe 1304.09 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,2)+last()+subscribe 922.20 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+take_last(1)+subscribe 1156.64 ns 18.32 ns 18.64 ns 0.98 19.57 ns
immediate_just(1,2,3)+element_at(1)+subscribe 857.27 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Schedulers

name rxcpp rpp prev rpp ratio rpp no optimization
immediate scheduler create worker + schedule 272.30 ns 0.47 ns 0.47 ns 1.00 0.62 ns
current_thread scheduler create worker + schedule 368.68 ns 4.35 ns 4.35 ns 1.00 4.66 ns
current_thread scheduler create worker + schedule + recursive schedule 829.37 ns 61.39 ns 61.18 ns 1.00 61.60 ns

Transforming Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+map(v*2)+subscribe 872.96 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+scan(10, std::plus)+subscribe 952.49 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+flat_map(immediate_just(v*2))+subscribe 2355.10 ns 124.58 ns 128.20 ns 0.97 185.53 ns
immediate_just+buffer(2)+subscribe 1582.63 ns 13.67 ns 13.99 ns 0.98 17.46 ns
immediate_just+window(2)+subscribe + subscsribe inner 2441.21 ns 1318.86 ns 1303.08 ns 1.01 1439.89 ns

Conditional Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take_while(false)+subscribe 867.22 ns - - 0.00 -
immediate_just+take_while(true)+subscribe 858.94 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Utility Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(1)+subscribe_on(immediate)+subscribe 2003.82 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Combining Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe 3505.83 ns 152.61 ns 179.98 ns 0.85 191.11 ns
immediate_just(1) + merge_with(immediate_just(2)) + subscribe 3701.50 ns 178.56 ns 157.01 ns 1.14 172.98 ns
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe - 145.44 ns 130.21 ns 1.12 158.12 ns
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe 3558.00 ns 417.13 ns 413.29 ns 1.01 380.14 ns
immediate_just(1) + zip(immediate_just(2)) + subscribe 2122.99 ns 214.28 ns 215.61 ns 0.99 208.75 ns
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe 3151.87 ns 240.61 ns 227.75 ns 1.06 253.13 ns

Subjects

name rxcpp rpp prev rpp ratio rpp no optimization
publish_subject with 1 observer - on_next 34.79 ns 14.81 ns 14.78 ns 1.00 15.07 ns
subscribe 100 observers to publish_subject 201727.20 ns 18657.15 ns 17502.83 ns 1.07 17809.69 ns
100 on_next to 100 observers to publish_subject 27269.16 ns 16806.52 ns 16865.09 ns 1.00 16935.40 ns

Scenarios

name rxcpp rpp prev rpp ratio rpp no optimization
basic sample 1442.21 ns 13.05 ns 13.98 ns 0.93 22.37 ns
basic sample with immediate scheduler 1453.89 ns 5.28 ns 5.28 ns 1.00 16.15 ns
mix operators with disposables and without disposables 6458.00 ns 1487.41 ns 1441.76 ns 1.03 1860.83 ns
single disposable and looooooong indentity chain 24792.57 ns 1070.77 ns 1063.55 ns 1.01 4773.36 ns

Aggregating Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+reduce(10, std::plus)+subscribe 910.68 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Error Handling Operators

name rxcpp rpp prev rpp ratio rpp no optimization
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe 2115.73 ns 1008.70 ns 1003.03 ns 1.01 1011.17 ns
create(on_error())+retry(1)+subscribe 588.05 ns 113.89 ns 109.58 ns 1.04 114.20 ns

ci-macos

General

name rxcpp rpp prev rpp ratio rpp no optimization
Subscribe empty callbacks to empty observable 390.44 ns 0.52 ns 0.47 ns 1.10 0.52 ns
Subscribe empty callbacks to empty observable via pipe operator 411.00 ns 0.49 ns 0.47 ns 1.04 0.50 ns

Sources

name rxcpp rpp prev rpp ratio rpp no optimization
from array of 1 - create + subscribe + immediate 858.90 ns 0.33 ns 0.33 ns 1.02 0.34 ns
from array of 1 - create + subscribe + current_thread 1080.70 ns 4.31 ns 3.75 ns 1.15 4.05 ns
concat_as_source of just(1 immediate) create + subscribe 2199.26 ns 180.03 ns 181.46 ns 0.99 181.30 ns
defer from array of 1 - defer + create + subscribe + immediate 774.04 ns 0.34 ns 0.34 ns 1.01 0.34 ns
interval - interval + take(3) + subscribe + immediate 2132.31 ns 57.08 ns 57.28 ns 1.00 59.25 ns
interval - interval + take(3) + subscribe + current_thread 2609.59 ns 32.78 ns 32.84 ns 1.00 32.75 ns
from array of 1 - create + as_blocking + subscribe + new_thread 20320.07 ns 23528.85 ns 20530.50 ns 1.15 24282.98 ns
from array of 1000 - create + as_blocking + subscribe + new_thread 26827.91 ns 23237.68 ns 27860.05 ns 0.83 39990.50 ns
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe 3374.13 ns 197.18 ns 199.42 ns 0.99 201.54 ns

Filtering Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take(1)+subscribe 1161.60 ns 0.34 ns 0.34 ns 0.99 0.34 ns
immediate_just+filter(true)+subscribe 880.36 ns 0.33 ns 0.35 ns 0.96 0.34 ns
immediate_just(1,2)+skip(1)+subscribe 1145.52 ns 0.34 ns 0.34 ns 1.00 0.34 ns
immediate_just(1,1,2)+distinct_until_changed()+subscribe 885.12 ns 0.34 ns 0.34 ns 0.99 0.34 ns
immediate_just(1,2)+first()+subscribe 1405.19 ns 0.34 ns 0.34 ns 1.00 0.34 ns
immediate_just(1,2)+last()+subscribe 1050.96 ns 0.82 ns 1.01 ns 0.82 0.72 ns
immediate_just+take_last(1)+subscribe 1155.80 ns 0.32 ns 0.34 ns 0.94 0.35 ns
immediate_just(1,2,3)+element_at(1)+subscribe 833.17 ns 0.34 ns 0.34 ns 1.01 0.34 ns

Schedulers

name rxcpp rpp prev rpp ratio rpp no optimization
immediate scheduler create worker + schedule 321.11 ns 0.51 ns 0.52 ns 0.98 0.52 ns
current_thread scheduler create worker + schedule 459.23 ns 4.13 ns 4.17 ns 0.99 4.18 ns
current_thread scheduler create worker + schedule + recursive schedule 753.71 ns 65.18 ns 66.02 ns 0.99 66.35 ns

Transforming Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+map(v*2)+subscribe 853.60 ns 2.55 ns 2.69 ns 0.95 2.78 ns
immediate_just+scan(10, std::plus)+subscribe 1025.33 ns 0.33 ns 0.34 ns 0.97 0.34 ns
immediate_just+flat_map(immediate_just(v*2))+subscribe 2184.68 ns 215.96 ns 210.93 ns 1.02 200.55 ns
immediate_just+buffer(2)+subscribe 1022.52 ns 16.23 ns 15.74 ns 1.03 16.34 ns
immediate_just+window(2)+subscribe + subscsribe inner 2056.44 ns 1076.69 ns 1081.37 ns 1.00 1093.22 ns

Conditional Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take_while(false)+subscribe 874.59 ns - - 0.00 -
immediate_just+take_while(true)+subscribe 822.99 ns 0.35 ns 0.36 ns 0.97 0.34 ns

Utility Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(1)+subscribe_on(immediate)+subscribe 1968.41 ns 2.02 ns 2.13 ns 0.95 2.01 ns

Combining Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe 3212.44 ns 226.47 ns 222.36 ns 1.02 225.81 ns
immediate_just(1) + merge_with(immediate_just(2)) + subscribe 3974.46 ns 214.55 ns 218.55 ns 0.98 220.75 ns
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe - 235.48 ns 223.77 ns 1.05 227.34 ns
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe 3313.84 ns 550.06 ns 549.89 ns 1.00 557.29 ns
immediate_just(1) + zip(immediate_just(2)) + subscribe 2211.57 ns 378.16 ns 335.10 ns 1.13 384.74 ns
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe 3029.03 ns 342.61 ns 346.13 ns 0.99 355.56 ns

Subjects

name rxcpp rpp prev rpp ratio rpp no optimization
publish_subject with 1 observer - on_next 45.75 ns 22.46 ns 22.83 ns 0.98 23.90 ns
subscribe 100 observers to publish_subject 136047.71 ns 18719.95 ns 18566.21 ns 1.01 17804.49 ns
100 on_next to 100 observers to publish_subject 31523.29 ns 11836.38 ns 12384.41 ns 0.96 11532.40 ns

Scenarios

name rxcpp rpp prev rpp ratio rpp no optimization
basic sample 1205.41 ns 10.68 ns 10.98 ns 0.97 31.94 ns
basic sample with immediate scheduler 1216.45 ns 5.35 ns 5.54 ns 0.97 10.39 ns
mix operators with disposables and without disposables 5887.91 ns 1411.56 ns 1451.38 ns 0.97 1734.43 ns
single disposable and looooooong indentity chain 16749.34 ns 1735.56 ns 1749.24 ns 0.99 3883.27 ns

Aggregating Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+reduce(10, std::plus)+subscribe 1046.35 ns 0.32 ns 0.34 ns 0.95 0.40 ns

Error Handling Operators

name rxcpp rpp prev rpp ratio rpp no optimization
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe 3714.84 ns 2915.60 ns 2889.55 ns 1.01 3078.19 ns
create(on_error())+retry(1)+subscribe 749.54 ns 187.52 ns 187.85 ns 1.00 230.95 ns

ci-ubuntu-clang

General

name rxcpp rpp prev rpp ratio rpp no optimization
Subscribe empty callbacks to empty observable 269.74 ns 0.64 ns 1.55 ns 0.41 0.65 ns
Subscribe empty callbacks to empty observable via pipe operator 272.14 ns 0.64 ns 1.55 ns 0.41 0.64 ns

Sources

name rxcpp rpp prev rpp ratio rpp no optimization
from array of 1 - create + subscribe + immediate 562.20 ns 0.31 ns 0.31 ns 1.00 0.31 ns
from array of 1 - create + subscribe + current_thread 815.82 ns 4.04 ns 4.04 ns 1.00 4.04 ns
concat_as_source of just(1 immediate) create + subscribe 2366.96 ns 130.50 ns 131.42 ns 0.99 139.70 ns
defer from array of 1 - defer + create + subscribe + immediate 778.35 ns 0.31 ns 0.31 ns 1.00 0.31 ns
interval - interval + take(3) + subscribe + immediate 2216.49 ns 58.71 ns 58.65 ns 1.00 58.66 ns
interval - interval + take(3) + subscribe + current_thread 3152.18 ns 31.13 ns 31.09 ns 1.00 31.71 ns
from array of 1 - create + as_blocking + subscribe + new_thread 42639.60 ns 31979.11 ns 32637.95 ns 0.98 33006.35 ns
from array of 1000 - create + as_blocking + subscribe + new_thread 42827.46 ns 38546.00 ns 38288.17 ns 1.01 39627.62 ns
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe 3700.93 ns 148.89 ns 149.68 ns 0.99 147.10 ns

Filtering Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take(1)+subscribe 1174.42 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+filter(true)+subscribe 850.80 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,2)+skip(1)+subscribe 1091.42 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,1,2)+distinct_until_changed()+subscribe 891.87 ns 0.33 ns 0.32 ns 1.03 0.32 ns
immediate_just(1,2)+first()+subscribe 1407.56 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,2)+last()+subscribe 1020.89 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+take_last(1)+subscribe 1193.85 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just(1,2,3)+element_at(1)+subscribe 869.08 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Schedulers

name rxcpp rpp prev rpp ratio rpp no optimization
immediate scheduler create worker + schedule 281.71 ns 1.55 ns 0.64 ns 2.44 1.55 ns
current_thread scheduler create worker + schedule 396.21 ns 4.04 ns 4.35 ns 0.93 4.04 ns
current_thread scheduler create worker + schedule + recursive schedule 853.68 ns 55.01 ns 55.33 ns 0.99 55.10 ns

Transforming Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+map(v*2)+subscribe 846.61 ns 0.31 ns 0.31 ns 1.00 0.31 ns
immediate_just+scan(10, std::plus)+subscribe 974.90 ns 0.62 ns 0.62 ns 1.00 0.33 ns
immediate_just+flat_map(immediate_just(v*2))+subscribe 2243.63 ns 139.90 ns 138.78 ns 1.01 137.41 ns
immediate_just+buffer(2)+subscribe 1541.83 ns 14.30 ns 13.99 ns 1.02 14.61 ns
immediate_just+window(2)+subscribe + subscsribe inner 2478.76 ns 917.59 ns 911.39 ns 1.01 915.58 ns

Conditional Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take_while(false)+subscribe 847.36 ns - - 0.00 -
immediate_just+take_while(true)+subscribe 860.85 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Utility Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(1)+subscribe_on(immediate)+subscribe 2025.29 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Combining Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe 3295.60 ns 161.78 ns 162.26 ns 1.00 156.61 ns
immediate_just(1) + merge_with(immediate_just(2)) + subscribe 3804.16 ns 143.02 ns 140.20 ns 1.02 141.50 ns
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe - 143.31 ns 143.08 ns 1.00 139.46 ns
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe 3437.82 ns 379.34 ns 380.34 ns 1.00 381.85 ns
immediate_just(1) + zip(immediate_just(2)) + subscribe 2253.52 ns 198.56 ns 201.11 ns 0.99 197.32 ns
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe 3242.16 ns 225.07 ns 224.52 ns 1.00 260.19 ns

Subjects

name rxcpp rpp prev rpp ratio rpp no optimization
publish_subject with 1 observer - on_next 52.66 ns 19.78 ns 19.33 ns 1.02 20.34 ns
subscribe 100 observers to publish_subject 208487.00 ns 17463.44 ns 17478.62 ns 1.00 17442.97 ns
100 on_next to 100 observers to publish_subject 40887.85 ns 20229.59 ns 20236.96 ns 1.00 20293.42 ns

Scenarios

name rxcpp rpp prev rpp ratio rpp no optimization
basic sample 1301.15 ns 11.50 ns 11.49 ns 1.00 21.43 ns
basic sample with immediate scheduler 1312.90 ns 5.90 ns 5.90 ns 1.00 6.53 ns
mix operators with disposables and without disposables 6549.21 ns 1177.15 ns 1178.52 ns 1.00 1477.07 ns
single disposable and looooooong indentity chain 27668.56 ns 1243.81 ns 1255.32 ns 0.99 4624.44 ns

Aggregating Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+reduce(10, std::plus)+subscribe 1001.18 ns 0.31 ns 0.31 ns 1.00 0.31 ns

Error Handling Operators

name rxcpp rpp prev rpp ratio rpp no optimization
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe 2182.59 ns 1169.84 ns 1176.43 ns 0.99 1174.19 ns
create(on_error())+retry(1)+subscribe 682.08 ns 139.13 ns 138.46 ns 1.00 148.15 ns

ci-windows

General

name rxcpp rpp prev rpp ratio rpp no optimization
Subscribe empty callbacks to empty observable 556.07 ns 2.16 ns 2.16 ns 1.00 1.85 ns
Subscribe empty callbacks to empty observable via pipe operator 572.10 ns 2.16 ns 2.16 ns 1.00 1.85 ns

Sources

name rxcpp rpp prev rpp ratio rpp no optimization
from array of 1 - create + subscribe + immediate 1155.57 ns 4.93 ns 4.94 ns 1.00 5.55 ns
from array of 1 - create + subscribe + current_thread 1419.82 ns 15.75 ns 15.74 ns 1.00 15.45 ns
concat_as_source of just(1 immediate) create + subscribe 3696.46 ns 174.60 ns 174.62 ns 1.00 178.05 ns
defer from array of 1 - defer + create + subscribe + immediate 1180.65 ns 5.24 ns 5.24 ns 1.00 5.24 ns
interval - interval + take(3) + subscribe + immediate 3736.36 ns 139.81 ns 139.74 ns 1.00 142.29 ns
interval - interval + take(3) + subscribe + current_thread 3460.30 ns 60.15 ns 59.86 ns 1.00 62.80 ns
from array of 1 - create + as_blocking + subscribe + new_thread 123175.00 ns 118700.00 ns 120400.00 ns 0.99 119788.89 ns
from array of 1000 - create + as_blocking + subscribe + new_thread 132655.56 ns 135675.00 ns 136975.00 ns 0.99 137275.00 ns
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe 5329.67 ns 206.57 ns 201.39 ns 1.03 215.13 ns

Filtering Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take(1)+subscribe 1818.86 ns 19.42 ns 19.42 ns 1.00 21.36 ns
immediate_just+filter(true)+subscribe 1610.58 ns 18.50 ns 18.51 ns 1.00 21.59 ns
immediate_just(1,2)+skip(1)+subscribe 2008.80 ns 17.89 ns 17.91 ns 1.00 21.60 ns
immediate_just(1,1,2)+distinct_until_changed()+subscribe 1328.95 ns 20.67 ns 20.68 ns 1.00 26.86 ns
immediate_just(1,2)+first()+subscribe 2372.16 ns 18.20 ns 18.21 ns 1.00 19.43 ns
immediate_just(1,2)+last()+subscribe 1464.98 ns 19.13 ns 19.15 ns 1.00 22.84 ns
immediate_just+take_last(1)+subscribe 2023.02 ns 64.85 ns 64.93 ns 1.00 70.17 ns
immediate_just(1,2,3)+element_at(1)+subscribe 1622.12 ns 20.97 ns 20.98 ns 1.00 21.63 ns

Schedulers

name rxcpp rpp prev rpp ratio rpp no optimization
immediate scheduler create worker + schedule 477.39 ns 4.32 ns 4.32 ns 1.00 4.32 ns
current_thread scheduler create worker + schedule 648.68 ns 11.11 ns 11.11 ns 1.00 11.11 ns
current_thread scheduler create worker + schedule + recursive schedule 1079.50 ns 103.96 ns 101.36 ns 1.03 103.12 ns

Transforming Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+map(v*2)+subscribe 1328.23 ns 18.80 ns 18.80 ns 1.00 21.63 ns
immediate_just+scan(10, std::plus)+subscribe 1422.12 ns 20.96 ns 20.96 ns 1.00 23.80 ns
immediate_just+flat_map(immediate_just(v*2))+subscribe 3837.33 ns 186.30 ns 185.11 ns 1.01 223.46 ns
immediate_just+buffer(2)+subscribe 2291.50 ns 64.26 ns 63.51 ns 1.01 72.33 ns
immediate_just+window(2)+subscribe + subscsribe inner 3974.07 ns 1216.92 ns 1192.15 ns 1.02 1226.57 ns

Conditional Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+take_while(false)+subscribe 1305.28 ns 17.57 ns 17.57 ns 1.00 19.13 ns
immediate_just+take_while(true)+subscribe 1329.92 ns 18.50 ns 18.50 ns 1.00 21.60 ns

Utility Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(1)+subscribe_on(immediate)+subscribe 3205.02 ns 11.10 ns 11.11 ns 1.00 11.11 ns

Combining Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe 5054.46 ns 197.43 ns 195.27 ns 1.01 222.13 ns
immediate_just(1) + merge_with(immediate_just(2)) + subscribe 5710.11 ns 186.78 ns 178.89 ns 1.04 204.81 ns
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe - 195.15 ns 194.65 ns 1.00 199.56 ns
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe 6119.16 ns 444.60 ns 443.65 ns 1.00 489.05 ns
immediate_just(1) + zip(immediate_just(2)) + subscribe 3865.37 ns 538.25 ns 519.56 ns 1.04 516.04 ns
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe 4853.97 ns 314.42 ns 314.38 ns 1.00 325.14 ns

Subjects

name rxcpp rpp prev rpp ratio rpp no optimization
publish_subject with 1 observer - on_next 36.72 ns 29.42 ns 29.27 ns 1.01 30.01 ns
subscribe 100 observers to publish_subject 264250.00 ns 25013.33 ns 25450.00 ns 0.98 24830.23 ns
100 on_next to 100 observers to publish_subject 51881.82 ns 35939.39 ns 35922.58 ns 1.00 32997.22 ns

Scenarios

name rxcpp rpp prev rpp ratio rpp no optimization
basic sample 1853.25 ns 96.57 ns 96.80 ns 1.00 112.11 ns
basic sample with immediate scheduler 1857.89 ns 66.73 ns 68.51 ns 0.97 82.35 ns
mix operators with disposables and without disposables 9381.75 ns 1787.22 ns 1797.99 ns 0.99 2439.19 ns
single disposable and looooooong indentity chain 25641.46 ns 1655.18 ns 1630.37 ns 1.02 6267.21 ns

Aggregating Operators

name rxcpp rpp prev rpp ratio rpp no optimization
immediate_just+reduce(10, std::plus)+subscribe 1458.16 ns 19.11 ns 19.11 ns 1.00 22.83 ns

Error Handling Operators

name rxcpp rpp prev rpp ratio rpp no optimization
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe 1896.36 ns 357.24 ns 353.06 ns 1.01 380.86 ns
create(on_error())+retry(1)+subscribe 1721.11 ns 138.15 ns 137.92 ns 1.00 139.85 ns

@AlexInLog AlexInLog merged commit 1e0c196 into v2 Feb 15, 2026
59 of 75 checks passed
@AlexInLog AlexInLog deleted the fix_busy_loop branch February 15, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant